package com.payment.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.payment.entity.common.UserNoCardOrder;
import com.payment.entity.common.UserOrderPackage;
import com.payment.entity.common.UserOrderPayment;
import com.payment.entity.payresults.PayPalNotificationPaymentResults;
import com.payment.entity.payresults.PayPalPaymentResults;
import com.payment.entity.payresults.PaypalNotificationpaymentResultsReversed;
import com.payment.entity.payresults.WeiXinNotificationPaymentResults;
import com.payment.entity.purchase.request.RequestPurchaseService;
import com.payment.entity.purchase.response.ResponsePurchaseService;
import com.payment.service.NotificationpaymentService;
import com.payment.service.UserNoCardOrderService;
import com.payment.service.UserOrderPackageService;
import com.payment.service.UserOrderPaymentService;
import com.payment.utils.HttpUtil;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;

@Service("utilsService")
@Transactional(rollbackFor = Exception.class)

/**
 * 公共工具服务实现类
 *
 * @author: lm
 * @date: 2019-12-05 10:58
 */

public class CommonUtilsServiceImpl {

    private static Logger logger = Logger.getLogger(CommonUtilsServiceImpl.class);
    @Resource
    private NotificationpaymentService notifytService;

    @Resource
    private UserOrderPackageService orderService;

    @Resource
    private UserOrderPaymentService paymentService;

    @Resource
    private UserNoCardOrderService noCardService;

    /**
     * 去订购套餐的路径：分测试路径和正式路径，在配置文件这边一起管理
     */
    @Value("${purchase.url}")
    private String PURCHASE_URL;

    /***
     *  将微信回传的交易记录入库保存下来
     * @param bank_type
     * @param appid
     * @param cash_fee
     * @param fee_type
     * @param is_subscribe
     * @param mch_id
     * @param nonce_str
     * @param openid
     * @param out_trade_no
     * @param result_code
     * @param return_code
     * @param sign
     * @param time_end
     * @param total_fee
     * @param trade_type
     * @param transaction_id
     * @return
     */
    public void insertWeixinResults(String bank_type, String appid, String cash_fee, String fee_type, String is_subscribe, String mch_id, String nonce_str, String openid, String out_trade_no, String result_code, String return_code, String sign, String time_end, String total_fee, String trade_type, String transaction_id) {

        WeiXinNotificationPaymentResults re = new WeiXinNotificationPaymentResults();
        re.setTransactionId(transaction_id);
        re.setBankType(bank_type);
        re.setAppid(appid);
        re.setCashFee(cash_fee);
        re.setFeeType(fee_type);
        re.setIsSubscribe(is_subscribe);
        re.setMchId(mch_id);
        re.setNonceStr(nonce_str);
        re.setOpenid(openid);
        re.setOutTradeNo(out_trade_no);
        re.setResultCode(result_code);
        re.setReturnCode(return_code);
        re.setSign(sign);
        re.setTimeEnd(time_end);
        re.setTotalFee(total_fee);
        re.setTradeType(trade_type);
        notifytService.insertPaymentResults(re);
    }

    /***
     * 成功的回调数据入库：根据支付id和金额入库：user_order_payment_t
     * @param payId
     * @param payAmount
     * @param fee_type
     * @param transaction_id
     */
    public void updatePaymentRst(String payId, String payAmount, String fee_type, String transaction_id, String payType, String payRst) {

        UserOrderPayment payment = new UserOrderPayment();
        payment.setPayId(payId);
        payment.setPayCurrency(fee_type);
        payment.setPayAmount(payAmount);
        payment.setPayType(payType);
        payment.setPayRst(payRst);
        payment.setTransactionId(transaction_id);
        paymentService.updateWeiXinPayRst(payment);
    }

    /**
     * 无卡订单支付结果入库：user_nocard_order_t
     *
     * @param payId
     */
    public void updateNoCardPayRst(String payId, String payRst) {
        UserNoCardOrder noCardOrder = new UserNoCardOrder();
        noCardOrder.setPayId(payId);
        noCardOrder.setPayRst(payRst);
        noCardService.updatePayRst(noCardOrder);
    }

    /***
     *发起向业务系统去订购套餐的请求
     *
     * @param partnerCode
     * @param secret
     * @param deviceCode
     * @param packageName
     * @param packageCode
     * @param packageType
     * @param orderPeriod
     * @param payAmount
     * @param buyType
     * @param priceType
     * @param salesType
     * @param payId
     * @param orderNo
     * @param payRst
     * @param payType
     * @return
     */
    public ResponsePurchaseService purchase(String partnerCode, String secret, String deviceCode, String packageName, String packageCode, String packageType, String orderPeriod, String payAmount, String buyType, String priceType, String salesType, String payId, String orderNo, String payRst, String payType) {

        //支付结果通知回到数据库从支付平台会跳转到订购套餐服务项目去执行业务：
        RequestPurchaseService pur = new RequestPurchaseService();
        pur.setPartnerCode(partnerCode);
        pur.setSecret(secret);
        pur.setDeviceCode(deviceCode);
        pur.setPackageName(packageName);
        pur.setPackageCode(packageCode);
        pur.setPackageType(packageType);
        pur.setOrderPeriod(orderPeriod);
        pur.setAmount(payAmount);
        pur.setBuyType(buyType);
        pur.setPriceType(priceType);
        pur.setSalesType(salesType);
        pur.setPayId(payId);
        pur.setOrderNo(orderNo);
        pur.setPayRst(payRst);
        pur.setPayType(payType);

        // 开始组装json
        String requestStr = JSON.toJSONString(pur);
        logger.info("【订购套餐】请求：" + requestStr);
        // 发送post请求，并接收返回结果
        String returnStr = HttpUtil.httpPost(PURCHASE_URL, requestStr);
        logger.info("url=" + PURCHASE_URL);

        logger.info("【订购套餐】响应：" + returnStr);
        ResponsePurchaseService re = JSONArray.parseObject(returnStr, ResponsePurchaseService.class);
        return re;
    }

    /***
     * paypal的IPN回调记录入库
     * @param mc_gross
     * @param invoice
     * @param payment_status
     * @param mc_currency
     * @param txn_id
     * @param protection_eligibility
     * @param address_status
     * @param payer_id
     * @param address_street
     * @param payment_date
     * @param charset
     * @param address_zip
     * @param first_name
     * @param mc_fee
     * @param address_country_code
     * @param address_name
     * @param notify_version
     * @param custom
     * @param payer_status
     * @param business
     * @param address_country
     * @param address_city
     * @param quantity
     * @param verify_sign
     * @param payer_email
     * @param payment_type
     * @param last_name
     * @param address_state
     * @param receiver_email
     * @param payment_fee
     * @param receiver_id
     * @param txn_type
     * @param item_name
     * @param item_number
     * @param residence_country
     * @param receipt_id
     * @param transaction_subject
     * @param payment_gross
     * @param ipn_track_id
     */
    public void insertPaypalIpnResults(String mc_gross, String invoice, String payment_status, String mc_currency, String txn_id, String protection_eligibility, String address_status, String payer_id,
                                       String address_street, String payment_date, String charset, String address_zip, String first_name, String mc_fee, String address_country_code, String address_name, String notify_version, String custom, String payer_status, String business, String address_country, String address_city, String quantity, String verify_sign, String payer_email, String payment_type, String last_name, String address_state, String receiver_email, String payment_fee, String receiver_id, String txn_type, String item_name, String item_number, String residence_country, String receipt_id, String transaction_subject, String payment_gross, String ipn_track_id) {

        PayPalNotificationPaymentResults results = new PayPalNotificationPaymentResults();
        results.setMc_gross(mc_gross);
        results.setAmount(mc_gross);
        results.setOrderNumber(invoice);
        results.setInvoice(invoice);
        results.setPayment_status(payment_status);
        results.setPaymentStatus(payment_status);
        results.setMc_currency(mc_currency);
        results.setMcCurrency(mc_currency);
        results.setTxn_id(txn_id);
        results.setTxnId(txn_id);
        results.setProtection_eligibility(protection_eligibility);
        results.setAddress_status(address_status);
        results.setPayer_id(payer_id);
        results.setAddress_street(address_street);
        results.setPayment_date(payment_date);
        results.setCharset(charset);
        results.setAddress_zip(address_zip);
        results.setFirst_name(first_name);
        results.setMc_fee(mc_fee);
        results.setAddress_country_code(address_country_code);
        results.setAddress_name(address_name);
        results.setNotify_version(notify_version);
        results.setCustom(custom);
        results.setPayer_status(payer_status);
        results.setBusiness(business);
        results.setAddress_country(address_country);
        results.setAddress_city(address_city);
        results.setQuantity(quantity);
        results.setVerify_sign(verify_sign);
        results.setPayer_email(payer_email);
        results.setPayment_type(payment_type);
        results.setLast_name(last_name);
        results.setAddress_state(address_state);
        results.setReceiver_email(receiver_email);
        results.setPayment_fee(payment_fee);
        results.setReceipt_id(receiver_id);
        results.setTxn_type(txn_type);
        results.setItem_name(item_name);
        results.setItem_number(item_number);
        results.setResidence_country(residence_country);
        results.setReceipt_id(receipt_id);
        results.setTransaction_subject(transaction_subject);
        results.setPayment_gross(payment_gross);
        results.setIpn_track_id(ipn_track_id);

        notifytService.insertPaymentResultsPaypal(results);
    }

    /***
     * paypal申诉退款记录
     * @param mc_gross
     * @param invoice
     * @param payment_status
     * @param mc_currency
     * @param txn_id
     * @param protection_eligibility
     * @param address_status
     * @param payer_id
     * @param address_street
     * @param payment_date
     * @param charset
     * @param address_zip
     * @param first_name
     * @param mc_fee
     * @param address_country_code
     * @param address_name
     * @param notify_version
     * @param custom
     * @param payer_status
     * @param business
     * @param address_country
     * @param address_city
     * @param quantity
     * @param verify_sign
     * @param payer_email
     * @param payment_type
     * @param last_name
     * @param address_state
     * @param receiver_email
     * @param payment_fee
     * @param receiver_id
     * @param txn_type
     * @param item_name
     * @param item_number
     * @param residence_country
     * @param receipt_id
     * @param transaction_subject
     * @param payment_gross
     * @param ipn_track_id
     */
    public void insertPaypalReversed(String mc_gross, String invoice, String payment_status, String mc_currency, String txn_id, String protection_eligibility, String address_status, String payer_id, String address_street, String payment_date, String charset, String address_zip, String first_name, String mc_fee, String address_country_code, String address_name, String notify_version, String custom, String payer_status, String business, String address_country, String address_city, String quantity, String verify_sign, String payer_email, String payment_type, String last_name, String address_state, String receiver_email, String payment_fee, String receiver_id, String txn_type, String item_name, String item_number, String residence_country, String receipt_id, String transaction_subject, String payment_gross, String ipn_track_id) {

        PaypalNotificationpaymentResultsReversed results = new PaypalNotificationpaymentResultsReversed();
        results.setMc_gross(mc_gross);
        results.setAmount(mc_gross);
        results.setOrderNumber(invoice);
        results.setInvoice(invoice);
        results.setPayment_status(payment_status);
        results.setPaymentStatus(payment_status);
        results.setMc_currency(mc_currency);
        results.setMcCurrency(mc_currency);
        results.setTxn_id(txn_id);
        results.setTxnId(txn_id);
        results.setProtection_eligibility(protection_eligibility);
        results.setAddress_status(address_status);
        results.setPayer_id(payer_id);
        results.setAddress_street(address_street);
        results.setPayment_date(payment_date);
        results.setCharset(charset);
        results.setAddress_zip(address_zip);
        results.setFirst_name(first_name);
        results.setMc_fee(mc_fee);
        results.setAddress_country_code(address_country_code);
        results.setAddress_name(address_name);
        results.setNotify_version(notify_version);
        results.setCustom(custom);
        results.setPayer_status(payer_status);
        results.setBusiness(business);
        results.setAddress_country(address_country);
        results.setAddress_city(address_city);
        results.setQuantity(quantity);
        results.setVerify_sign(verify_sign);
        results.setPayer_email(payer_email);
        results.setPayment_type(payment_type);
        results.setLast_name(last_name);
        results.setAddress_state(address_state);
        results.setReceiver_email(receiver_email);
        results.setPayment_fee(payment_fee);
        results.setReceipt_id(receiver_id);
        results.setTxn_type(txn_type);
        results.setItem_name(item_name);
        results.setItem_number(item_number);
        results.setResidence_country(residence_country);
        results.setReceipt_id(receipt_id);
        results.setTransaction_subject(transaction_subject);
        results.setPayment_gross(payment_gross);
        results.setIpn_track_id(ipn_track_id);

        notifytService.insertPaypalReversed(results);
    }

    /***
     *paypal的Webhook回调记录入库
     * @param id
     * @param state
     * @param payId
     * @param payment_mode
     * @param protection_eligibility
     * @param protection_eligibility_type
     * @param parent_payment
     * @param total
     * @param currency
     * @param subtotal
     * @param value
     * @param currencys
     */
    public void insertPaypalWebhookResults(String id, String state, String payId, String payment_mode, String protection_eligibility, String protection_eligibility_type, String parent_payment, String total, String currency, String subtotal, String value, String currencys) {

        PayPalPaymentResults results = new PayPalPaymentResults();
        results.setPaypal_id(id);
        results.setState(state);
        results.setInvoice_number(payId);
        results.setPayment_mode(payment_mode);
        results.setProtection_eligibility(protection_eligibility);
        results.setProtection_eligibility_type(protection_eligibility_type);
        results.setParent_payment(parent_payment);
        results.setTotal(total);
        results.setCurrency(currency);
        results.setSubtotal(subtotal);
        results.setTransaction_fee(value);
        results.setTransaction_fee_currency(currencys);
        notifytService.addPaypalpaymentResults(results);
    }

    /***
     * 成功的回调数据入库：根据支付id和金额入库：user_order_package_t
     * @param fee_type
     * @param transaction_id
     */
    public Integer updatePayRst(String payId, String payAmount, String fee_type, String settlePrice, String transaction_id, String payType, String payRst, String isNotify, String payAccount) {

        // 成功的回调数据入库：根据支付id和金额入库：user_order_package_t
        UserOrderPackage order = new UserOrderPackage();
        order.setOrderStatus("3");
        order.setPayId(payId);
        order.setPayCurrency(fee_type);
        order.setPayAmount(payAmount);
        order.setSettlePrice(settlePrice);
        order.setPayType(payType);
        order.setPayRst(payRst);
        order.setIsNotify(isNotify);
        order.setPayAccount(payAccount);
        order.setTransactionId(transaction_id);
        order.setPayStatus("1");
        order.setPayResultDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        return orderService.updateWeiXinPayRst(order);
    }

    /***
     *將user_order_package_hist_t数据更新
     * @param payId
     * @param payAmount
     * @param fee_type
     * @param transaction_id
     * @param payType
     * @param payRst
     * @param isNotify
     * @param payAccount
     * @return
     */
    public Integer updatePayRstForHist(String payId, String payAmount, String fee_type, String settlePrice, String transaction_id, String payType, String payRst, String isNotify, String payAccount) {

        // 成功的回调数据入库：根据支付id和金额入库：user_order_package_hist_t
        UserOrderPackage order = new UserOrderPackage();
        order.setOrderStatus("3");
        order.setPayId(payId);
        order.setPayCurrency(fee_type);
        order.setPayAmount(payAmount);
        order.setSettlePrice(settlePrice);
        order.setPayType(payType);
        order.setPayRst(payRst);
        order.setIsNotify(isNotify);
        order.setPayAccount(payAccount);
        order.setTransactionId(transaction_id);
        order.setPayStatus("1");
        order.setPayResultDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        return orderService.updatePayRstForHist(order);
    }

    /***
     * 入库user_order_package_t
     * @param partnerCode
     * @param partnerName
     * @param deviceCode
     * @param iccId
     * @param packageCode
     * @param packageName
     * @param packageType
     * @param buyType
     * @param priceType
     * @param salesType
     * @param globalOrder
     * @param orderPeriod
     * @param requestOrderId
     * @param orderNo
     * @param orderId
     * @param payId
     * @param payAmount
     * @param payCurrency
     * @param partnerScope
     * @param packageFee
     * @param expressFee
     * @param cardFee
     * @param orderStatus
     * @param payType
     * @param payRst
     * @param isNotify
     * @param payAccount
     * @param transactionId
     * @param createDate
     * @return
     */
    public Integer insertOrderToOrderT(String partnerCode, String partnerName, String deviceCode, String iccId, String packageCode, String packageName, String packageType,
                                       String buyType, String priceType, String salesType, String globalOrder, String orderPeriod, String requestOrderId, String orderNo,
                                       String orderId, String payId, String payAmount, String payCurrency, String settlePrice, String partnerScope,
                                       String packageFee, String expressFee, String cardFee, String orderStatus, String payType, String payRst, String isNotify,
                                       String payAccount, String transactionId, Timestamp createDate) {

        UserOrderPackage order = new UserOrderPackage();
        order.setPartnerCode(partnerCode);
        order.setPartnerName(partnerName);
        order.setDeviceCode(deviceCode);
        order.setIccId(iccId);
        order.setPackageCode(packageCode);
        order.setPackageName(packageName);
        order.setPackageType(packageType);
        order.setBuyType(buyType);
        order.setPriceType(priceType);
        order.setSalesType(salesType);
        order.setGlobalOrder(globalOrder);
        order.setOrderPeriod(orderPeriod);
        order.setRequestOrderId(requestOrderId);
        order.setOrderNo(orderNo);
        order.setOrderId(orderId);
        order.setPayId(payId);
        order.setPayAmount(payAmount);
        order.setPayCurrency(payCurrency);
        order.setSettlePrice(settlePrice);
        order.setPartnerScope(partnerScope);
        order.setPackageFee(packageFee);
        order.setExpressFee(expressFee);
        order.setCardFee(cardFee);
        order.setOrderStatus(orderStatus);
        order.setPayType(payType);
        order.setPayRst(payRst);
        order.setIsNotify(isNotify);
        order.setPayAccount(payAccount);
        order.setTransactionId(transactionId);
        order.setCreateDate(createDate);
        order.setPayStatus("1");
        order.setPayResultDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        return orderService.insertOrderToOrderT(order);
    }

    public void updatePaymentForHist(String payId, String payAmount, String fee_type, String transaction_id, String payType, String payRst) {

        UserOrderPayment payment = new UserOrderPayment();
        payment.setPayId(payId);
        payment.setPayCurrency(fee_type);
        payment.setPayAmount(payAmount);
        payment.setPayType(payType);
        payment.setPayRst(payRst);
        payment.setTransactionId(transaction_id);
        paymentService.updatePaymentForHist(payment);

    }

    public Integer insertOrderToPaymentT(String partnerCode, String requestOrderId, String payId, String transactionId, String payAmount, String payCurrency, String payType, String payRst) {

        UserOrderPayment payment = new UserOrderPayment();
        payment.setPartnerCode(partnerCode);
        payment.setTransactionId(requestOrderId);
        payment.setPayId(payId);
        payment.setPayCurrency(payCurrency);
        payment.setPayAmount(payAmount);
        payment.setPayType(payType);
        payment.setPayRst(payRst);
        payment.setTransactionId(transactionId);
        return paymentService.insertOrderToPaymentT(payment);

    }
}
